<?php

# 什么是事务？
    # 用户在更改数据的过程中，可能有其他用户发起更改请求，事务就是保证数据库记录的更新从一个一致性状态到另一个一致性状态的操作过程。

# 事务 ACID 属性
    # 原子性（Atomicity）：事务是一个不可分割的工作单位，事务中的操作要么都发生，要么都不发生。
        # 侧重点在于增删改，要么都成功，要么都不成功
    # 一致性（Consistency）：事务必须使数据库从一个一致性状态变换到另一个一致性状态。
        # 所有规则必须应用到事务的修改中
        # 事务执行前后，数据库所有数据（包括事务操作数据）必须合法（符合所有制定的规则），以维护全体数据的完整性
    # 隔离性（Isolation）：多用户并发访问数据库，数据库为每个用户开启的事务，他们的操作数据不能互相干扰，事务之间保持隔离。
        # 事务未提交的数据不被其他事务读取
        # 事务多次执行相同查询得到相同结果（行号对应，且对应行数据一致）
    # 持久性（Durability）：事务提交后，对数据库的改变是永久的，不受数据库故障的影响。
        # 保证事务提交成功时，事务操作已全部写入磁盘

# 事务小结
    # 一致性是目的，原子性、隔离性、持久性是手段

# 事务并发问题
    # 脏读：事务读取到其他事务回滚前的数据。
        # 读取到其他事务弃用的修改
    # 不可重复读：事务前后两次查询得到不同的结果（期间有其他事务提交 update）。
        # 相同数据行的内容不同
    # 幻读：事务前后两次查询结果的数据行不对应，即多行或少行（期间有其他事务提交 insert/delete）。
        # 数据行不对应

# 事务隔离级别
    # 0 未提交读（read uncommitted）：事务未提交修改对其他事务可见。
    # 1 已提交读（read committed）：事务从开始到提交前，相关修改对其他事务不可见；前后执行相同查询可能得到不同的结果（期间其他事务提交了修改），也叫不可重复读（nonrepeatable read）。
    # 2 可重复读（repeatable read）：事务期间，对其他事务提交的 update 不可见，但是对其他事务提交的 insert/delete 可见。
    # 3 可串行化（serializable）：强制事务串行执行，每次读需要获得表级共享锁，读写相互都会阻塞。

# 事务隔离级别效果
    # 隔离级别　　脏读　　不可重复读　　幻读
    # 未提交读　　是　　　是　　　　　　是
    # 已提交读　　否　　　是　　　　　　是    # 多数数据库采用，如：oracle
    # 可重复读　　否　　　否　　　　　　是    # MySQL 采用，通过多版本并发控制（MVCC）解决幻读问题
    # 快照　　　　否　　　否　　　　　　否
    # 可序列化　　否　　　否　　　　　　否

# InnoDB 可重复读底层实现原理
    # 使用多版本并发控制（MVCC），每行添加一个版本号，数据修改，版本号+1
    # 读取事务开始时，系统给事务当前版本号，事务读取版本号<=当前版本号的数据
    # 事务开始时，当且晋档可重复读隔离级别，创建快照（一致性可读视图）
    #
